package com.sangeng.service.serviceimpl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.constants.SystemConstants;
import com.sangeng.domain.ResponseResult;
import com.sangeng.domain.dto.AddCategoryDto;
import com.sangeng.domain.dto.UpdateCategoryDto;
import com.sangeng.domain.entity.Article;
import com.sangeng.domain.entity.Category;
import com.sangeng.domain.vo.CategoryVo;
import com.sangeng.domain.vo.PageVo;
import com.sangeng.enums.AppHttpCodeEnum;
import com.sangeng.exception.SystemException;
import com.sangeng.mapper.ArticleMapper;
import com.sangeng.mapper.CategoryMapper;
import com.sangeng.service.CategoryService;
import com.sangeng.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    //    private final ArticleService articleService;
    private final ArticleMapper articleMapper;

    @Override
    public ResponseResult<List<CategoryVo>> getCategoryList() {
        //查询文章表
        LambdaQueryWrapper<Article> articleWrapper = new LambdaQueryWrapper<>();
        //判断是否正常发布状态
        articleWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        List<Article> articles = articleMapper.selectList(articleWrapper);
        //articleService.list(articleWrapper);

        //获取文章的分类id 并且去重(不同文章可能在同一个分类id下面）
        //为什么需要获取文章的分类id，因为用户会点击超链接进去分类页面的详情页下
        //当进入详情页的时候，我们需要展示该分类下的所有文章，怎么查？利用分类id在分类表中查，所以我们需要分类id
        //利用Strem流获取到id，然后把流对象封装为一个xxx数据结构返回，在这里用的是toSet，封装为集合返回。
        Set<Long> categoryIds = articles.stream()
                .map(Article::getCategoryId)
                .collect(Collectors.toSet());

        //查询分类表 要求分类状态是正常
        List<Category> categories = listByIds(categoryIds);

        categories = categories.stream().filter(category -> {//过滤文章是否为正常状态
            return SystemConstants.STATUS_NORMAL.equals(category.getStatus());
        }).collect(Collectors.toList());

        //封装vo
        List<CategoryVo> categoryVoList = BeanCopyUtils.copyBeanList(categories, CategoryVo.class);
        return ResponseResult.okResult(categoryVoList);
    }

    @Override
    public ResponseResult<List<CategoryVo>> getAllCategoryList() {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getStatus, SystemConstants.NORMAL);
        List<Category> list = list(wrapper);

        //封装vo
        List<CategoryVo> categoryVoList = BeanCopyUtils.copyBeanList(list, CategoryVo.class);
        return ResponseResult.okResult(categoryVoList);
    }

    @Override
    public ResponseResult<PageVo> getCategoryList(Integer pageNum, Integer pageSize) {
        Page<Category> categoryPage = new Page<>(pageNum, pageSize);
        //查询未被删除的category 由于设置了自动拼接del_flg查询，所以传入wrapper不用自己填
        Page<Category> page = page(categoryPage, null);
        List<Category> categorylist = page.getRecords();
        List<CategoryVo> categoryVoList = BeanCopyUtils.copyBeanList(categorylist, CategoryVo.class);
        long total = page.getTotal();
        PageVo pageVo = new PageVo(categoryVoList, total);
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult<String> addCategory(AddCategoryDto categoryDto) {
        //数据体对应的实体类是category 要先进行转换然后才能存入
        Category category = BeanCopyUtils.copyBean(categoryDto, Category.class);
        boolean save = save(category);
        if (save) {
            return ResponseResult.okResult();
        } else {
            throw new SystemException(AppHttpCodeEnum.CATEGORY_INSERT_FAILED);
        }
    }

    @Override
    public ResponseResult<String> updateCategory(UpdateCategoryDto categoryDto) {
        Category category = BeanCopyUtils.copyBean(categoryDto, Category.class);
        boolean update = updateById(category);
        if (update) {
            return ResponseResult.okResult();
        } else {
            throw new SystemException(AppHttpCodeEnum.CATEGORY_UPDATE_ERROR);
        }
    }

    @Override
    public ResponseResult<String> deleteCategoryById(List<Long> idList) {
        //开发中删除基本都是逻辑删除 把del_flag改为1 实际上是更新操作
//        idList
//                .forEach(
//                        id -> {
//                            UpdateWrapper<Category> wrapper = new UpdateWrapper<>();
//                            wrapper.eq("id",id).set("del_flag", 1);
//                            boolean update = update(wrapper);
//                            if(!update) {
//                                throw new SystemException(AppHttpCodeEnum.CATEGORY_DELETE_ERROR);
//                            }
//                        }
//                );
        if (CollectionUtils.isNotEmpty(idList)) {
            boolean update = lambdaUpdate().set(Category::getDelFlag, 1).in(Category::getId, idList).update();
            return update ? ResponseResult.okResult() : ResponseResult.errorResult(AppHttpCodeEnum.CATEGORY_DELETE_ERROR);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_ERROR);
    }

    private final CategoryMapper categoryMapper;

    @Override
    public ResponseResult<CategoryVo> getCategoryById(Long id) {
        Category category = categoryMapper.selectById(id);
        //显示在页面的是VO
        CategoryVo categoryVo = BeanCopyUtils.copyBean(category, CategoryVo.class);
        return ResponseResult.okResult(categoryVo);
    }

/**
 * TODO 把判断是否成功抽象为一个函数 但是错误码不一样怎么整- - 不懂
 private void isSucceed(boolean flag) {

 }*/
}
